
////////////////////////////////////////////////////////////////////////////////
//
// Salt.java
//
// Copyright © (C) 2010
// 
// Emory Hughes Merryman, III
// emory.merryman@gmail.com
// 
// All Rights Reserved
// 
// This file is part of Interworks.
// 
// Interworks is free software: you can 
// redistribute it and/or modify it under 
// the terms of the GNU General Public 
// License as published by the Free 
// Software Foundation, either version 3 
// of the License, or (at your option) any 
// later version.
// 
// This program is distributed in the hope 
// that it will be useful, but WITHOUT 
// ANY WARRANTY; without even the 
// implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR 
// PURPOSE.  See the GNU General Public 
// License for more details.
//
// You should have received a copy of the 
// GNU General Public License along with 
// this program.  If not, see 
// <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////////////

package
    com . superiorglobalbusiness . cB7zEmeT ;

import javax . xml . transform . Transformer ;
import javax . xml . transform . TransformerFactory ;
import javax . xml . transform . stream . StreamSource ;
import javax . xml . transform . dom . DOMResult ;
import org . w3c . dom . Node ;
import java . util . List ;
import org . docx4j . openpackaging . packages . PresentationMLPackage ;
import org . pptx4j . jaxb . Context ;
import org . docx4j . XmlUtils ;
import java . util . Collections ;
import java . util . Map ;
import java . util . HashMap ;
import javax . xml . namespace . NamespaceContext ;
import java . util . ArrayList ;
import org . pptx4j . pml . Shape ;
import org . pptx4j . pml . CxnSp ;
import org . docx4j . openpackaging . parts . Part ;
import org . docx4j . openpackaging . parts . PartName ;
import org . docx4j . openpackaging . parts . PresentationML . SlidePart ;
import java . io . File ;

import java . io . IOException ;
import javax . xml . transform . TransformerException ;
import javax . xml . transform . TransformerConfigurationException ;
import org . docx4j . openpackaging . exceptions . InvalidFormatException ;
import javax . xml . bind . JAXBException ;
import org . docx4j . openpackaging . exceptions . Docx4JException ;

class Salt
{
    public static void main ( String [ ] args )
    {
	if ( args . length != 2 )
	    {
		System . err . println ( "Useage:  java Main {input} {output}" ) ;
		System . exit ( 1 ) ;
	    }
	final String input = args [ 0 ] ;
	final String output = args [ 1 ] ;
	final Map < String , String > namespaceURI =
	    new HashMap < String , String > ( ) ;
	namespaceURI . put
	    ( "a" , "http://schemas.openxmlformats.org/drawingml/2006/main" ) ;
	namespaceURI . put
	    ( "r" , "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ) ;
	namespaceURI . put
	    ( "p" , "http://schemas.openxmlformats.org/presentationml/2006/main" ) ;
	final Map < String , String > prefix = new HashMap < String , String > ( ) ;
	for ( Map . Entry < String , String > entry : namespaceURI . entrySet ( ) )
	    {
		prefix . put ( entry . getValue ( ) , entry . getKey ( ) ) ;
	    }
	class Worker
	{
	    Transformer transformer ( )
	    {
		Transformer transformer = null ;
		try
		    {
			transformer =
			    TransformerFactory . newInstance ( ) .
			    newTransformer
			    (
			     new StreamSource
			     (
			      this . getClass ( ) .
			      getResourceAsStream
			      (
			       "/com/superiorglobalbusiness/cB7zEmeT/trees.xsl"
			       )
			      )
			     ) ;
		    }
		catch ( TransformerConfigurationException cause )
		    {
			assert false : cause ;
		    }
		catch ( TransformerException cause )
		    {
			assert false : cause ;
		    }
		return ( transformer ) ;
	    }


	    Node inputNode ( Transformer transformer )
	    {
		Node inputNode = null ;
		try
		    {
			final javax . xml . transform . stream . StreamResult sr =
			    new javax . xml . transform . stream . StreamResult
			    ( System . out ) ;
			transformer . transform ( new StreamSource ( input ) , sr ) ;

			DOMResult result = new DOMResult ( ) ;
			transformer . transform
			    ( new StreamSource ( input ) , result ) ;
			inputNode = result . getNode ( ) ;
		    }
		catch ( TransformerException cause )
		    {
			assert false : cause ;
		    }
		return ( inputNode ) ;
	    }

	    PresentationMLPackage pMLPackage ( )
	    {
		PresentationMLPackage pMLPackage = null ;
		try
		    {
			pMLPackage =
			    PresentationMLPackage . createPackage ( ) ;
		    }
		catch ( InvalidFormatException cause )
		    {
			assert false : cause ;
		    }
		return ( pMLPackage ) ;
	    }

	    PartName slide1 ( )
	    {
		PartName slide1 = null ;
		try
		    {
			slide1 = new PartName ( "/ppt/slides/slide1.xml" ) ;
		    }
		catch ( InvalidFormatException cause )
		    {
			assert false : cause ;
		    }
		return ( slide1 ) ;
	    }

	    List < Object >
		spOrGrpSpOrGraphicFrame
		( PresentationMLPackage pMLPackage )
	    {
		Part part = 
		    pMLPackage . getParts ( ) .
		    getParts ( ) .
		    get ( slide1 ( ) ) ;
		assert part instanceof SlidePart ;
		List < Object > spOrGrpSpOrGraphicFrame =
		    ( ( SlidePart ) ( part ) ) .
		    getJaxbElement ( ) .
		    getCSld ( ) .
		    getSpTree ( ) .
		    getSpOrGrpSpOrGraphicFrame ( ) ;
		return ( spOrGrpSpOrGraphicFrame ) ;
	    }

	    NamespaceContext namespaceContext ( )
	    {
		NamespaceContext namespaceContext =
		    new NamespaceContext ( )
		    {
			public String getNamespaceURI ( String prefix )
			{
			    return ( namespaceURI . get ( prefix ) ) ;
			}

			public String getPrefix ( String namespaceURI )
			{
			    return ( prefix . get ( namespaceURI ) ) ;
			}

			public java . util . Iterator < ? > getPrefixes
			    ( String namespaceURI )
			{
			    return
				(
				 Collections . singleton
				 ( getPrefix ( namespaceURI ) ) . iterator ( )
				 ) ;
			}
		    } ;
		return ( namespaceContext ) ;
	    }

	    < T >
		List < T >
		list
		(
		 Node inputNode ,
		 String xpath ,
		 Class < T > clazz ,
		 PresentationMLPackage pmlPackage
		 )
	    {
		List < T > shapes = new ArrayList < T > ( ) ;
		List < Node > nodes =
		    XmlUtils . xpath
		    (
		     inputNode ,
		     xpath ,
		     this . namespaceContext ( )
		     ) ;
		for ( Node node : nodes )
		    {
			item ( node , shapes , clazz , pmlPackage ) ;
		    }
		return ( shapes ) ;
	    }

	    <T > 
		void
		item
		(
		 Node node ,
		 List < T > list ,
		 Class < T > clazz ,
		 PresentationMLPackage pMLPackage
		 )
	    {
		try
		    {
			Object obj =
			    XmlUtils . unmarshal
			    (
			     node ,
			     Context . jcPML ,
			     clazz
			     ) ;
			spOrGrpSpOrGraphicFrame ( pMLPackage ) . add ( obj ) ;
			list . add ( clazz . cast ( obj ) ) ;
		    }
		catch ( JAXBException cause )
		    {
			assert false : cause ;
		    }
	    }

	    void arrange ( List < Shape > shapes )
	    {
		int step = 800000 ;
		int i = 0 ;
		for ( Shape shape : shapes )
		    {
			shape . getSpPr ( ) . getXfrm ( ) . getOff ( ) . setX ( i * step ) ;
			shape . getSpPr ( ) . getXfrm ( ) . getOff ( ) . setY ( i * step ) ;
			i ++ ;
		    }
	    }

	    void save ( PresentationMLPackage pMLPackage )
	    {
		try
		    {
			pMLPackage . save ( new File ( output ) ) ;
		    }
		catch ( Docx4JException cause )
		    {
			System . err . println ( "There was a problem saving the pptx file." ) ;
			System . exit ( 2 ) ;
		    }
	    }
	}
	Worker worker = new Worker ( ) ;
	Transformer transformer = worker . transformer ( ) ;
	Node inputNode = worker . inputNode ( transformer ) ;
	PresentationMLPackage pMLPackage = worker . pMLPackage ( ) ;
	List < Shape > shapes =
	    worker . list ( inputNode , "/data/p:sp" , Shape . class , pMLPackage ) ;
	worker . list ( inputNode , "/data/p:cxnSp" , CxnSp . class , pMLPackage ) ;
	worker . arrange ( shapes ) ;
	worker . save ( pMLPackage ) ;
    }

    private static final String TEST = "<p:spTree xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"><p:nvGrpSpPr xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><p:cNvPr id=\"1\" name=\"presentation slide\"/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"0\" cy=\"0\"/><a:chOff x=\"0\" y=\"0\"/><a:chExt cx=\"0\" cy=\"0\"/></a:xfrm></p:grpSpPr></p:spTree>" ;
}
